
/**
* 上海中赢金融信息服务有限公司
* Copyright (c) 2017-2027 Chinazyjr,Inc.All Rights Reserved.
*/
package com.sys.midware.redis.core.operation.impl;

import java.util.List;

import org.apache.log4j.Logger;

import com.sys.midware.redis.core.RedisFactory;
import com.sys.midware.redis.core.operation.AbstractOperations;
import com.sys.midware.redis.core.operation.ListOperations;
import com.sys.midware.redis.exceptions.BRedisException;
import com.sys.midware.redis.util.SerializationUtils;

import redis.clients.jedis.Jedis;

/**
 * <b>Description：</b> List 操作类 <br/>
 * <b>ClassName：</b> ListOperationsImpl <br/>
 * <b>@author：</b> jackyshang <br/>
 * <b>@date：</b> 2016年8月22日 下午4:11:23 <br/>
 * <b>@version: </b> <br/>
 */
public class ListOperationsImpl extends AbstractOperations implements ListOperations {

    private static Logger logger = Logger.getLogger(StringsOperationsImpl.class);

    private ListOperationsImpl() {
    };

    private static ListOperationsImpl instance;

    /**
     * 获取单例工厂
     * 
     * @return
     * @throws Exception
     */
    public static ListOperationsImpl getInstance() {
        if (instance != null)
            return instance;

        synchronized (ListOperationsImpl.class) {
            if (instance == null) {
                instance = new ListOperationsImpl();
            }
            return instance;
        }
    }

    @Override
    public <K, T> Long putList(K key, List<T> values) {

        Jedis jedis = getClient();
        try {
            Long l = null;
            if(!jedis.exists(rawKey(key))){
                l = jedis.rpush(rawKey(key), rawValues(values));
            }else{
                l =jedis.rpush(rawKey(key), rawValues(values));
            }
            return l;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> List<V> getFromListByPage(K key, int start, int end) {
        Jedis jedis = getClient();
        try {
            List<byte[]> re = jedis.lrange(rawKey(key), start, end);
            return SerializationUtils.deserialize(re);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> List<V> getFromList(K key) {
        Jedis jedis = getClient();
        try {
            List<byte[]> re = jedis.lrange(rawKey(key), 0, -1);
            return SerializationUtils.deserialize(re);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> Long push(K key, V value) {
        Jedis jedis = getClient();
        try {
            Long re = jedis.lpush(rawKey(key), rawValue(value));
            return re;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> V pop(K key) {
        Jedis jedis = getClient();
        try {
            byte[] re = jedis.lpop(rawKey(key));
            return deserializeValue(re);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> Long in(K key, V value) {
        Jedis jedis = getClient();
        try {
            Long re = jedis.rpush(rawKey(key), rawValue(value));
            return re;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> V out(K key) {
        Jedis jedis = getClient();
        try {
            byte[] re = jedis.lpop(rawKey(key));
            return deserializeValue(re);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K> Long size(K key) {
        Jedis jedis = getClient();
        try {
            Long re = jedis.llen(rawKey(key));
            return re;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public boolean delete(Object... keys) {
        Jedis jedis = getClient();
        boolean flag = false;
        try {

            for (Object obj : keys) {
                jedis.del(rawKey(obj));
            }
            flag = true;
            return flag;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }

    }

    @Override
    public <K, V> V index(K key, long index) {
        Jedis jedis = getClient();
        try {
            byte[] re = jedis.lindex(rawKey(key), index);
            return deserializeValue(re);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

    @Override
    public <K, V> String set(K key, long index, V value) {
        Jedis jedis = getClient();
        try {
            String re = jedis.lset(rawKey(key), index, rawValue(value));
            return re;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }

    }

    @Override
    public <K, V> String trim(K key, long start, long end) {
        Jedis jedis = getClient();
        try {
            String re = jedis.ltrim(rawKey(key), start, end);
            return re;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
            RedisFactory.close(jedis);
        }
    }

}
